package cn.ekuma.epos.datalogic.local;

import java.util.ArrayList;
import java.util.List;
import cn.ekuma.data.dao.bean.IKeyed;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public abstract class AbstractBaseDAO<T extends IKeyed<String>> {
	protected SQLiteOpenHelper helper;
	private static final String[] COUNT_COLUMN = { "COUNT(1)" };
	public static String ID="ID";
	
	public AbstractBaseDAO(SQLiteOpenHelper db) {
		this.helper = db;
	}

	public  boolean hasItems(){
		 SQLiteDatabase db = null;
		    Cursor cursor = null;
		    try {
		      db = helper.getReadableDatabase();
		      cursor = db.query(this.getTableName(), COUNT_COLUMN, null, null, null, null, null);
		      cursor.moveToFirst();
		      return cursor.getInt(0) > 0;
		    } finally {
		      close(cursor, db);
		   }
	}
	
	public T find(IKeyed<String> id){
		SQLiteDatabase db = null;
	    Cursor cursor = null;
	    try {
	      db = helper.getReadableDatabase();
	      cursor = db.query(getTableName(), 
	    		  getTableColumns(), 
	    		  getKeyColumn() + "=?",
                  new String[] { id.getKey() }, null, null, null);
	      if (cursor.moveToNext()) {
	          return readValues(cursor,null);
	      }
	      return null;
	    } finally {
	      close(cursor, db);
	    }
    }

    public abstract String getKeyColumn();

	public abstract T readValues(Cursor c, T obj);
    

	public abstract String[] getTableColumns() ;

	public boolean exist(IKeyed<String> id) {
		SQLiteDatabase db = null;
	    Cursor cursor = null;
	    try {
	      db = helper.getReadableDatabase();
	      cursor = db.query(getTableName(), 
	    		  COUNT_COLUMN,
	    		  getKeyColumn() + "=?",
                  new String[] { id.getKey() }, null, null, null);
	      cursor.moveToFirst();
	      return cursor.getInt(0) > 0;
	    } finally {
	      close(cursor, db);
	   }
    }

    public List<T> list()  {
    	ArrayList<T> retList=new ArrayList<T>();
    	SQLiteDatabase db = null;
        Cursor cursor = null;
        try {
          db = helper.getWritableDatabase();
          cursor = db.query(getTableName(), 
        	    		  getTableColumns(), 
        	    		  null,
                          null, null, null, null);

          while (cursor.moveToNext()) {
        	  retList.add(this.readValues(cursor, null));
          }
          return retList;
        } finally {
            close(cursor, db);
       }   
    }

    public int update(T t)  {
    	SQLiteDatabase db = null;    
	    Cursor cursor = null;
	    try {
	      db = helper.getWritableDatabase();
	      return db.update(getTableName(), 
	    		  createContentValues(t),
	    		  getKeyColumn() + "=?",
                  new String[] {t.getKey()});
	    } finally {
	      close(cursor, db);
	    }
    }

    public int delete(IKeyed<String> t) {
    	SQLiteDatabase db = null;
        Cursor cursor = null;
        try {
          db = helper.getWritableDatabase();      
          return db.delete(getTableName(), getKeyColumn() + "="+t.getKey(), null);     
        } finally {
          close(cursor, db);
        }
    }

    public long insert(T t){
        befareInsert(t);
        SQLiteDatabase db = null;
        try {
          db = helper.getWritableDatabase();      
          // Insert the new entry into the DB.
          return db.insert(getTableName(), null, createContentValues(t));
        } finally {
          close(null, db);
        }
    }
    
    public long insert(List<T> ts){ 	
        SQLiteDatabase db = null;
        try {
          db = helper.getWritableDatabase();       
          for(T t:ts){
        	  befareInsert(t);
        	  db.insert(getTableName(), null, createContentValues(t));
          }
          return 1;
        } finally {
          close(null, db);
        }
    }

    public abstract ContentValues createContentValues(T t);
    
    public abstract Class getSuportClass();
    
    
    public void clear() {
        SQLiteDatabase db = null;
    	try {
    	      db = helper.getWritableDatabase();      
    	      db.delete(getTableName(), null, null);
    	    } finally {
    	      close(null, db);
    	 }
    }

    public abstract String getTableName();
    
	public void befareInsert(T t) {
      
    }

    public void befareUpdate(T t){
    }

    public void befareDelete(IKeyed<String> key) {
    }
    
    
    
   protected  void close(Cursor cursor, SQLiteDatabase database) {
        if (cursor != null) {
          cursor.close();
        }
        if (database != null) {
          database.close();
        }
      }
   
	
   public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
	     db.execSQL("DROP TABLE IF EXISTS " + getTableName());
   } 
}
